function pageInit (){
    function init() {
        fixHeight();
        createTooltips();

        jQuery(".form").each(function() {
            if (jQuery(this).attr("id") != 'feedback')
                FormStyle(this);
        });
        
        //init menu hovers and last item round

        jQuery.fn.wait = function(time, type) {
            time = time || 1000;
            type = type || "fx";
            return this.queue(type, function() {
                var self = this;
                setTimeout(function() {
                    jQuery(self).dequeue();
                }, time);
            });
        };


        jQuery("#navigation > li:last.sep").remove();
        jQuery("#navigation > li:last").addClass("last");
        jQuery("#navigation > li:last > a").after("<b></b>");

        jQuery("#navigation > li").hover(function() {
            jQuery("#navigation ul li").css("display", "none");
            jQuery(this).find("ul li").fadeIn();
            jQuery(this).find("ul li").width(jQuery(this).find("ul").width());
        }, function() {
            jQuery("#navigation ul li").each(function() { jQuery(this).stop(false, true);});
            jQuery("#navigation ul li").css("display", "none");
        });
    }

    function fixHeight() {
        var winHeight = jQuery(window).height();

        var content = jQuery('#content');
        if (content.length > 0) {
            var height = winHeight - 91 - 64 - 20;
            content.css('minHeight', height + "px");
        }
    }

    init();
}

function EditQuestionForm(form, questionId) {
    this.form = form;
    this.questionId = questionId;
    var _this = this;

    form.submit(function() { return false; });

    form.find("#question-send").click(function() { sendData(false); });
    form.find("#send-to-approve").click(function() { sendData(true); });

    function sendData(approve) {
        $(this).attr('disabled', 'disabled');
        var queryString = 'testId=' + form.find('#testId').val();
        queryString += '&question=' + encodeURIComponent(form.find(".qtext textarea").val());
        queryString += '&questionDescription=' + encodeURIComponent(form.find('#question-description').val());
        if (_this.questionId) queryString += '&questionId=' + _this.questionId;

        var answersString = '', correctAnswers = '', answerNumber = 0;

        var answers = form.find('#question-answers .answer');
        jQuery.each(answers, function() {
            if ((jQuery(this).hasClass('incorrect') || jQuery(this).hasClass('correct')) && jQuery(this).find('textarea').val() != '') {
                var string = '&answer=';
                string += encodeURIComponent(jQuery(this).find('textarea').val());
                string += '&answerId=' + jQuery(this).attr('id');
                if (jQuery(this).find(':checked').length == 1) {
                    if (correctAnswers != '') correctAnswers += ',';
                    correctAnswers += answerNumber;
                }
                answersString += string;
                answerNumber++;
            }
        });

        form.qS = queryString;
        if (answersString != '' && answersString != 'undefined') {
            form.qS += answersString;
            if (correctAnswers.length > 0) form.qS += '&correct=' + correctAnswers;
        }
        if (approve) form.qS += "&approve="; 
        jQuery.ajax({
            type: "POST",
            cache: false,
            data: _this.form.qS,
            url: "/add_question",
            dataType: "json",
            success: function(data) {
                setErrors(data.errors);
                $('#question-send').removeAttr('disabled');

                if (data.errors.length == 0) {
                    if (_this.questionId) {
                        history.back(1);
                    } else {
                        var spanEl = jQuery('#showText');
                        spanEl.html('Добавить еще');
                        spanEl.css({fontSize:'1.4em', visibility:'visible'});

                        spanEl.before("<div id='question-thanks' style='color:green;padding:5px 0;margin-bottom:10px;font-size:1.2em;'>Большое спасибо за Ваш вопрос.</div>");

                        jQuery('#edit-question').css('display', 'none');
                        jQuery('#question-preview').css('display', 'none');

                        jQuery("#edit-question form :input").not("select, #testId, [type=button], [type=submit]").val("");
                        jQuery("#edit-question form :checkbox").removeAttr("checked");
                        var answers = jQuery('#question-answers .answer');
                        jQuery.each(answers, function(i) {
                            if (i > 0) jQuery(this).remove();
                            else jQuery(this).attr("class", "answer incorrect");
                        });
                    }
                }
            },
            error:function(xhr) {
                var status = 0;
                try {status = xhr.status;} catch(e){};
                if (status >= 400 && status <= 600) _this.form.html("<span style='color:red;'>Ошибка " + status + ". Пожалуйста, сообщите об этом разработчикам сервиса.</span>");
                else this.form.html("<span style='color:red;'>Ошибка соединения с сервером</span>");
            }
        });

    }

    form.find("img:last, a:last").click(function() {
        var preview = $("#question-preview");
        preview.css("display", "block");
        var qtext = cleanMarkup(form.find(".qtext textarea").val());
        preview.find(".q-text").html(qtext);

        var answers = form.find('#question-answers .answer');
        preview.find("ul").html('');
        $.each(answers, function() {
            var answerText;
            answerText = cleanMarkup($(this).find("textarea").val());

            if ($(this).find(':checked').length == 1)
                preview.find("ul").append("<li class='correct'></li>");
            else
                preview.find("ul").append("<li></li>");

            preview.find("ul li:last").html(answerText);
        });

        var dtext = cleanMarkup(form.find("#question-description").val());
        preview.find(".desc-text").html(dtext);
    });

    function cleanMarkup(text) {
        var t = text.replace(/</g, "&lt;");

        var nextTagIsOpen = true;
        var fromIndex = 0;
        var error = false;

        var alternT = '';
        while(true) {
            var open = t.indexOf("[code]", fromIndex);
            var close = t.indexOf("[/code]", fromIndex);
            if (open == -1 && close == -1 && nextTagIsOpen) break;

            if (nextTagIsOpen && open != -1 && open < close) {
                alternT += t.substring(fromIndex, open + 1).replace(/\n/g, '<br/>');
                fromIndex = open + 1;
                nextTagIsOpen = !nextTagIsOpen;
                continue;
            }

            if (!nextTagIsOpen && close != -1 && (close < open || open == -1)) {
                alternT += t.substring(fromIndex, close + 1);
                fromIndex = close + 1;
                nextTagIsOpen = !nextTagIsOpen;
                continue;
            }

            t = "<b style='color:red;font-weight:normal;'>Неправильное использование тега [code]</b>";
            error = true;
            break;
        }

        alternT += t.substring(fromIndex, t.length).replace(/\n/g, '<br/>');
        if (!error) {
            t = alternT.replace(/\[code\]/g, "<pre><code>").replace(/\[\/code\]/g, "</code></pre>");
        }

        return t;
    }

    function setErrors(errors) {
        var div = _this.form.find(".errors");
        div.html('');

        for(var i = 0; i < errors.length; i++)
            div.append("<div>" + errors[i] + "</div>");

        if (errors.length > 0) div.removeClass("hidden");
        else div.addClass("hidden");
    }

}

function simpleDateFormat(date, pattern) {
    function restore_zero(n) { return n >= 10 ? n : '0' + n; }
    return pattern.replace('dd', restore_zero(date.getDate())).replace('MM', restore_zero(date.getMonth() + 1)).replace('yyyy', date.getFullYear())
                  .replace('HH', restore_zero(date.getHours())).replace('mm', restore_zero(date.getMinutes())).replace('ss', restore_zero(date.getSeconds()));
}

/**
 * Создаем контейнер со ссылкой, раскрывающей комментарии к вопросу теста
 * и спаном с количеством комментариев
 * @param container контейнер, в который будут загружаться комментарии
 * @param topic идентификатор Topic-а
 * @param comments количество комментариев
 */
var QuestionComments = function(container, topic, comments, opened) {
    container = jQuery(container);
    container.addClass("hidden question-comments");

    var link = jQuery(document.createElement("a"));
    link.attr("href", "");
    link.html("Комментировать вопрос");

    link.click(function() {
        if (container.children().length == 0) {
            var span = jQuery(container).parent().find('span.comments-count');
            var panel = new Comments.Panel(topic, { onLoad: function(topic) { span.html('(всего: ' + topic.commentsInTopic + ')'); } });
            container.append(panel);
        }
        container.attr("class", container.attr("class").indexOf('hidden') != -1 ? 'question-comments' : 'question-comments hidden');
        return false;
    });

    if (opened) link.click();

    var wrapper = jQuery(document.createElement("div"));

    var commentsCount = jQuery(document.createElement("span"));
    commentsCount.addClass('comments-count');
    commentsCount.html('(всего: ' + comments + ')');

    wrapper.append(link);
    wrapper.append(commentsCount);

    return wrapper;
};

function Timer(timeLeft, elId) {
    this.base = new Date().getTime();
    this.timeLeft = timeLeft;
    this.el = document.getElementById(elId);

    var _this = this;

    function updateTimer() {
        var timeout = new Date(_this.base + _this.timeLeft - new Date().getTime());

        if (timeout > 0) {
            var minutes = timeout.getMinutes();
            var seconds = timeout.getSeconds();

            function format(n) { return n > 9 ? n : "0" + n; }

            _this.el.innerHTML = format(minutes) + ":" + format(seconds);

            setTimeout(updateTimer, 1000);
        } else {
            timeout = 0;
        }

    }

    updateTimer();
}

function Voter(elId, target, targetId, user) {
    this.el = $("#" + elId);
    var _this = this;

    var button = this.el.find("button");
    button.click(function() {
        $.ajax({
            type:"POST",
            dataType:"json",
            data:"id=" + targetId,
            cache:false,
            url:"/vote/" + target,
            success: function(data) {
                $("#post-info #votes").html(data.votes);
                $("#votePost span").html(data.votes);
                $("#voters").append("<nobr><img align='absmiddle' height='24' src='/user/" + user +"?avatar'/> <a href='/user/" + user +"'>" + user +"</a></nobr>&nbsp;&nbsp;");
                var b = _this.el.find("button");
                b.attr("disabled", "disabled");
                b.unbind("click");
                if ($("#voters").hasClass("closed"))
                    $("#showVoters").click();

                _this.el.find("img").hide();
            },
            beforeSend: function() {
                _this.el.find("img").show();
            },
            error: function(xhr) {
                var status = 0;
                try { status = xhr.status; } catch(e){};
                if (status >= 400  && status < 600) _this.el.html("<span style='color:red'>Ошибка " + status + "</span>");
                else _this.el.html("<span style='color:red'>Ошибка соединения с сервером</span>");
            }
        });
    });
}

function markupYoutube() {
    var url = jQuery(this).html();
    var _this = this;

    var successed = false;
    jQuery.ajax({
        type: 'GET',
        url: 'http://oohembed.com/oohembed/?url=' + escape(url) + '&format=json',
        cache: false,
        dataType: 'jsonp',
        success:function(data) {
            jQuery(_this).html("<div>" + data.html + "</div>");
            successed = true;
        }
    });
    if (!successed) jQuery(_this).html("<a href='" + url + "'>" + url + "</a>");
}

function Markup() {
    jQuery(".comments .comment-block > .text").each(function() {
        var html = jQuery(this).html();
        html = html.replace(/&lt;img ([^&]+[^g]+[^t]+[^;]+)\/&gt;/g, '<img $1/>');
        html = html.replace(/&lt;a href='([^&]+[^g]+[^t]+[^;]+)'&gt;([^&]+[^g]+[^t]+[^;]+)&lt;\/a&gt;/g, "<a href='$1'>$2</a>");
        html = html.replace(/&lt;span class='youtube'&gt;([^&]+[^g]+[^t]+[^;]+)&lt;\/span&gt;/g, "<span class='youtube'>$1</span>");
        jQuery(this).html(html);
        jQuery(this).find("span.youtube").each(markupYoutube);
    });    
}

function ShareThis(container, url, title, description) {
    // VK
    container.append(VK.Share.button({url: url, title: title, description: description, noparse : true},
        {type: "round", text: "Поделиться"}));

    // Facebook
    var u = new String(url).replace('http://', '');
    container.append('<a name="fb_share" type="button_count" share_url="' + encodeURIComponent(u) + '" href="http://www.facebook.com/sharer.php?u=' +
                     encodeURIComponent(u) + '&t=' + encodeURIComponent(title) + '">' +
                     'Share</a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>');

    // Google Buzz
    container.append("<a href='http://www.google.com/buzz/post'" +
                     "class='google-buzz-button' title='Post to Google Buzz'" +
                     "data-url='" + url + "'" +
                     "data-imageurl='http://quizful.net/res/img/logo.png'" +
                     "data-button-style='small-count'></a>");

    container.append("<script type='text/javascript' src='http://www.google.com/buzz/api/button.js'></script>");

    // Twitter
    container.append('<a href="http://twitter.com/share" class="twitter-share-button" ' +
                    'data-count="horizontal" data-via="quizful">Tweet</a>' +
                    '<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>');    
}

function feedAction(action, object, container, showText) {
    container.append('<a class="followBlock"><img src="/res/img/' + action + '.png" class="' + action + '" /></a>');
    var a = container.find("a.followBlock:last-child");

    if (action == 'follow')
        a.attr('title', 'Подписаться на обновления');
    else if (action == 'unfollow')
        a.attr('title', 'Отписаться от обновления');

    a.find('img').click(function() {
        jQuery.ajax({
            type: 'POST',
            url: '/' + action + '/' + object,
            cache:false,
            dataType: 'json',
            success: function(data) {
                if (data == '0') {
                    a.css({color: 'green', 'font-size': '13px'});
                    if (showText) {
                        if (action == 'follow')
                            a.html("Вы успешно подписаны на обновления");
                        else if (action == 'unfollow')
                            a.html("Вы успешно отписались от обновлений");
                        a.fadeOut(2500);
                    } else { a.remove(); feedAction(action == 'follow' ? 'unfollow' : 'follow', object, container, showText); }
                } else {
                    a.css({color: 'red', 'font-size': '13px'});
                    a.html("Запрос выполнился с ошибкой");
                }
            },
            error:function(xhr) {
                var status = 0;
                try { status = xhr.status; } catch(e) {};
                a.css({color: 'red', 'font-size': '13px'});
                if (status >= 400 && status < 600) a.html("Ошибка " + status);
                else a.html("Ошибка соединения с сервером");
            }
        });
        return false;
    });
}